package com.cndw.kungfu.model;

import java.io.Serializable;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

import com.cndw.kungfu.core.CacheDataBase;
import com.cndw.kungfu.core.CacheDataKey;
import com.cndw.kungfu.ext.LogUtil;
import com.cndw.kungfu.model.activity.domain.CrossServer;
import com.cndw.kungfu.model.pvp.api.ApiCore;
import com.cndw.kungfu.model.pvp.war.WarConfig;
import com.cndw.kungfu.model.pvp.war.WarCoreCenter;
import com.cndw.kungfu.model.pvp.war.WarCrossData;
import com.cndw.kungfu.model.pvp.war.WarFlower;
import com.cndw.kungfu.model.pvp.war.WarPlayer;

/**
 * 华山论剑跨服站的数据入口
 * 
 * @author fantadust [9677889@qq.com]
 * @date 2012-7-12 下午2:55:41
 */
public class CrossProxySerialize extends CacheDataBase implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 7024956230993646298L;

	private static CrossProxySerialize instance = null;

	private CrossProxySerialize() {
	}

	@Override
	public String getKey() {
		return CacheDataKey.keyCrossProxySerialize;
	}

	public static CrossProxySerialize getInstance() {
		if (instance == null) {
			synchronized (CrossProxySerialize.class) {
				if (instance == null) {
					CacheDataBase cacheData = Context.getSysServer().initCacheData(CacheDataKey.keyCrossProxySerialize);
					if (cacheData != null && cacheData instanceof CrossProxySerialize) {
						instance = (CrossProxySerialize) cacheData;
					}
					if (instance == null) {
						instance = new CrossProxySerialize();
					}
					if (instance.headIds == null) {
						instance.headIds = new ConcurrentHashMap<Long, Integer>();
					}
					if (instance.getSyncDBTime() == 0) {
						instance.commitSync();
					}
					instance.check();
				}
			}

		}
		return instance;

	}

	/**
	 * 头像列表
	 */
	private ConcurrentHashMap<Long, Integer> headIds = new ConcurrentHashMap<Long, Integer>();
	private int headCycle = 0;
	/**
	 * 献花的记录
	 */
	private ConcurrentLinkedQueue<WarFlower> warFlowersList = new ConcurrentLinkedQueue<WarFlower>();

	/**
	 * 3个类型比赛 12单服 34跨服 56 全服
	 */
	private int[] stateWar = new int[8];
	/**
	 * 单服冠军id
	 */
	private long singleBoss;
	private Map<Integer, WarPlayer> crossBossMap;
	
	
	
	public void addFlowerLog(WarFlower warFlower) {
		warFlowersList.add(warFlower);
		while (warFlowersList.size() > 8) {
			warFlowersList.poll();
		}
	}

	public LinkedList<WarFlower> getWarFlowers() {
		if (warFlowersList==null || warFlowersList.isEmpty()) {
			return new LinkedList<WarFlower>();
		}
		return new LinkedList<WarFlower>(warFlowersList);
	}

	private static transient Map<Long, Integer> crossAwardMap = new ConcurrentHashMap<Long, Integer>();
	private static transient Map<Long, Integer> worldAwardMap = new ConcurrentHashMap<Long, Integer>();

	public boolean awardAdd(long uid, int camType) {
		int oldCam = crossAwardMap.containsKey(uid) ? crossAwardMap.get(uid) : 0;
		boolean ok = oldCam != camType;
		if (ok) {
			crossAwardMap.put(uid, camType);
		}
		return ok;
	}

	public boolean awardAddWorld(long uid, int camType) {
		int oldCamType = worldAwardMap.containsKey(uid) ? worldAwardMap.get(uid) : 0;
		boolean ok = oldCamType != camType;
		if (ok) {
			worldAwardMap.put(uid, camType);
		}
		return ok;
	}

	private static transient Map<Long, Integer> crossBetMap = new ConcurrentHashMap<Long, Integer>();
	private static transient Map<Long, Integer> worldBetMap = new ConcurrentHashMap<Long, Integer>();

	public boolean betAward(long uid, int camType) {
		int oldC = crossBetMap.containsKey(uid) ? crossBetMap.get(uid) : 0;
		boolean ok = oldC == 0 || oldC > camType;
		if (ok) {
			crossBetMap.put(uid, camType);
		}
		return ok;
	}

	public boolean betAwardWorld(long uid, int camType) {
		int oldC = worldBetMap.containsKey(uid) ? worldBetMap.get(uid) : 0;
		boolean ok = oldC == 0 || oldC > camType;
		if (ok) {
			worldBetMap.put(uid, camType);
		}
		return ok;
	}

	public void worldHIdAdd(long uid, int hid) {
		headIds.put(uid, hid);
	}

	public int worldHidGet(long uid) {
		return headIds.containsKey(uid) ? headIds.get(uid) : 0;
	}

	public int getHeadCycle() {
		return headCycle;
	}


	
	public synchronized void check(){
		if (warFlowersList == null) {
			warFlowersList = new ConcurrentLinkedQueue<WarFlower>();
		}
		if (ApiCore.isCrossServer()) {
			Set<Integer> oks = new HashSet<Integer>();
			for (CrossServer e : CrossServer.getAll()) {
				if (e.getType() <= 0) {
					continue;
				}
				if (oks.contains(e.getType())) {
					continue;
				}
				WarCrossData warCrossData = WarCoreCenter.getCrossData(e.getType());
				warCrossData.upBoss();
				oks.add(e.getType());
			}	
		}		
	}

	public synchronized void stateWar(int type, int step, int camType) {
		try {
			if (stateWar == null || stateWar[0] != WarConfig.getCycle()) {
				stateWar = new int[8];
				stateWar[0] = WarConfig.getCycle();
				crossAwardMap.clear();
				crossBetMap.clear();
				worldAwardMap.clear();
				worldBetMap.clear();
				LogUtil.getMain().debug("war init clear " + WarConfig.getCycle());
			}
			stateWar[type * 2 + 1] = step;
			stateWar[type * 2 + 2] = camType;
			if (type == 2 && camType == 32) {
				headCycle = WarConfig.getCycle();
				headIds.clear();
				LogUtil.getMain().info("war cross clear " + headIds);
			}
			LogUtil.getMain().debug(" type " + type + " step " + step + " camType " + camType);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public int[] getStateWar() {
		if (stateWar == null) {
			synchronized (this) {
				if (stateWar == null) {
					stateWar = new int[8];
				}
			}
		}
		return stateWar;
	}

	public int getCrossStep() {
		if (stateWar == null || stateWar.length != 8) {
			return 0;
		}
		return stateWar[3];
	}

	public long getSingleBoss() {
		return singleBoss;
	}

	public void setSingleBoss(long singleBoss) {
		this.singleBoss = singleBoss;
	}

	public WarPlayer getCrossBoss(int area) {
		if (crossBossMap == null) {
			crossBossMap = new ConcurrentHashMap<Integer, WarPlayer>();
		}
		return crossBossMap.get(area);
	}

	public synchronized void setCrossBoss(int area, WarPlayer crossBoss) {
		if (crossBossMap == null) {
			crossBossMap = new ConcurrentHashMap<Integer, WarPlayer>();
		}
		if (crossBoss  != null){
			crossBossMap.put(area, crossBoss);
		}
	}

}
